'*****************************************************************************
'
' "Open source" kit for CM-CIC P@iement(TM).
' Process CMCIC Payment. Sample RFC2104 compliant with PHP4 skeleton.
'
' File "CMCIC_Tpe.vb" :
'
' Author   : Euro-Information/e-Commerce (contact: centrecom@e-i.com)
' Version  : 1.04
' Date     : 01/01/2009
'
' Copyright: (c) 2009 Euro-Information. All rights reserved.
' License  : see attached document "Licence.txt".
'
' *****************************************************************************

Imports System
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Data
Imports System.Security.Cryptography
Imports System.Text
Imports NEvoWeb.Modules.NB_Store.SharedFunctions

Namespace NEvoWeb.Modules.NB_Store.Gateway

    Public Class CMCIC

        Protected oTpe As CMCIC_Tpe
        Protected oHmac As CMCIC_Hmac
        Public sReference As String
        Public sMontant As String
        Public sDevise As String
        Public sLangue As String
        Public sDate As String
        Public sTexteLibre As String
        Public sEmail As String
        Public sOptions As String

        Public sNbrEch As String = ""
        Public sDateEcheance1 As String = ""
        Public sMontantEcheance1 As String = ""
        Public sDateEcheance2 As String = ""
        Public sMontantEcheance2 As String = ""
        Public sDateEcheance3 As String = ""
        Public sMontantEcheance3 As String = ""
        Public sDateEcheance4 As String = ""
        Public sMontantEcheance4 As String = ""

        Private sDataToValidate As String

        Public Sub New(ByVal oInfo As NEvoWeb.Modules.NB_Store.NB_Store_OrdersInfo)

            LoadSettings(oInfo)

            oTpe = New CMCIC_Tpe(oInfo)

            sDataToValidate = sNumero & "*" & sDate & "*" & sMontantForm & "*" & Me.sReference & "*" & Me.sTexteLibre & "*" & sVersion & "*" & sLangueForm & "*" & sCodeSociete & "*" & Me.sEmail & "*" _
                            & Me.sNbrEch & "*" _
                            & Me.sDateEcheance1 & "*" & Me.sMontantEcheance1 & "*" _
                            & Me.sDateEcheance2 & "*" & Me.sMontantEcheance2 & "*" _
                            & Me.sDateEcheance3 & "*" & Me.sMontantEcheance3 & "*" _
                            & Me.sDateEcheance4 & "*" & Me.sMontantEcheance4 & "*"

            oHmac = New CMCIC_Hmac(oTpe)


        End Sub

        Public Sub LoadSettings(ByVal oInfo As NEvoWeb.Modules.NB_Store.NB_Store_OrdersInfo)
            Dim strXMLSettings As String = GetStoreSetting(oInfo.PortalID, "CMCIC.gateway", GetCurrentCulture)

            If strXMLSettings <> "" Then

                Dim setParams As Hashtable = ParseGateway(strXMLSettings)

                Dim OrderTotal As String = oInfo.Total.ToString("0.00")
                'OrderTotal = System.Text.RegularExpressions.Regex.Replace(OrderTotal, "[^0-9]", "")

                Me.sReference = DateTime.Now.ToString("mmss") & oInfo.OrderID
                Me.sDevise = setParams("sDevise")
                Me.sMontant = OrderTotal
                Me.sLangue = GetCurrentCountryCode()
                Me.sTexteLibre = ""
                Me.sEmail = oInfo.Email
                Me.sOptions = GetCurrentCulture()

                Me.sTexteLibre = oInfo.OrderID.ToString & ";" & CurrentCart.getCartID(oInfo.PortalID) & ";" & GetCurrentCulture()

                Me.sDate = DateTime.Now.ToString("dd/MM/yyyy:HH:mm:ss")

            End If

        End Sub

        Public Function isValidHmac(ByVal sChaineMAC As String, ByVal sMAC As String) As Boolean
            Return oHmac.isValidHmac(sChaineMAC, sMAC)
        End Function


        Public ReadOnly Property HmacString() As String

            Get
                Return sDataToValidate
            End Get

        End Property

        Public ReadOnly Property HmacControlString() As String

            Get
                Return "V1.04.sha1.aspx-VB.NET-[CtlHmac" & sVersion & sNumero & "]-" & oHmac.computeHmac("CtlHmac" & sVersion & sNumero)
            End Get

        End Property

        Public ReadOnly Property sMAC() As String

            Get
                Return oHmac.computeHmac(HmacString)
            End Get

        End Property

        Public ReadOnly Property sMontantForm() As String

            Get
                Return Me.sMontant + Me.sDevise
            End Get

        End Property

        Public ReadOnly Property sVersion() As String

            Get
                Return oTpe.sVersion
            End Get

        End Property

        Public ReadOnly Property sNumero() As String

            Get
                Return oTpe.sNumero
            End Get

        End Property

        Public ReadOnly Property sLangueForm() As String

            Get
                Return oTpe.sLangue
            End Get

        End Property

        Public ReadOnly Property sCodeSociete() As String

            Get
                Return oTpe.sCodeSociete
            End Get

        End Property


        Public ReadOnly Property sUrlOk() As String

            Get
                Return oTpe.sUrlOk
            End Get

        End Property

        Public ReadOnly Property sUrlKo() As String

            Get
                Return oTpe.sUrlKo
            End Get

        End Property


        Public ReadOnly Property sUrlPaiement() As String

            Get
                Return oTpe.sUrlPaiement
            End Get

        End Property

        Public ReadOnly Property MacKey() As String

            Get
                Return oTpe.sCle
            End Get

        End Property

    End Class

    Partial Public Class CMCIC_Tpe

        Const CMCIC_URLPAIEMENT As String = "paiement.cgi"
        Public sVersion As String
        Public sNumero As String
        Public sLangue As String
        Public sCodeSociete As String
        Public sUrlOk As String
        Public sUrlKo As String
        Public sUrlPaiement As String

        Private _sCle As String

        Public Sub New(ByVal oInfo As NEvoWeb.Modules.NB_Store.NB_Store_OrdersInfo)
            LoadSettings(oInfo)
        End Sub

        Public ReadOnly Property sCle() As String
            Get
                Return Me._sCle
            End Get
        End Property

        Public Sub LoadSettings(ByVal oInfo As NEvoWeb.Modules.NB_Store.NB_Store_OrdersInfo)
            Dim strXMLSettings As String = GetStoreSetting(oInfo.PortalID, "CMCIC.gateway", GetCurrentCulture)

            If strXMLSettings <> "" Then

                Dim setParams As Hashtable = ParseGateway(strXMLSettings)


                Dim returnURL As String = setParams("CMCIC_URLOK")  ' URL that the payment provider will return the client to.
                Dim cancelURL As String = setParams("CMCIC_URLKO") ' URL to return the client if the payment failed.

                '-------------------------------------------------
                'The URL taken from the settings have tokens included for certain values.
                'We need to replace these tokens with the actual values from the order.
                returnURL = Replace(returnURL, "[ORDERID]", oInfo.OrderID.ToString)
                cancelURL = Replace(cancelURL, "[ORDERID]", oInfo.OrderID.ToString)
                returnURL = Replace(returnURL, "[LANG]", GetCurrentCulture)
                cancelURL = Replace(cancelURL, "[LANG]", GetCurrentCulture)
                returnURL = returnURL.Trim
                cancelURL = cancelURL.Trim
                '-------------------------------------------------


                Me.sVersion = setParams("CMCIC_VERSION")
                Me._sCle = setParams("CMCIC_CLE")
                Me.sNumero = setParams("CMCIC_TPE")
                Me.sUrlOk = returnURL
                Me.sUrlKo = cancelURL
                Me.sUrlPaiement = setParams("CMCIC_SERVEUR") & CMCIC_URLPAIEMENT
                Me.sCodeSociete = setParams("CMCIC_CODESOCIETE")
                Me.sLangue = NB_Store.SharedFunctions.GetCurrentCountryCode()

            End If

        End Sub



    End Class



    Public Class CMCIC_Hmac


        Private _sUsableKey As Byte()

        Public Sub New(ByVal oTpe As CMCIC_Tpe)

            _sUsableKey = _getUsableKey(oTpe)

        End Sub


        Private Function _getUsableKey(ByVal oTpe As CMCIC_Tpe) As Byte()

            Dim hexStrKey As String = oTpe.sCle.Substring(0, 38)
            Dim hexFinal As String = oTpe.sCle.Substring(38, 2) & "00"

            Dim cca0 As Int32 = Convert.ToInt32(hexFinal(0))

            If (cca0 > 70 And cca0 < 97) Then
                hexStrKey &= Convert.ToChar(cca0 - 23) & hexFinal.Substring(1, 1)
            Else
                If (hexFinal.Substring(1, 1) = "M") Then
                    hexStrKey &= hexFinal.Substring(0, 1) & "0"
                Else
                    hexStrKey &= hexFinal.Substring(0, 2)
                End If
            End If

            Return hexStringToByteArray(hexStrKey)

        End Function

        Public Function computeHmac(ByVal sData As String) As String

            Dim TpeHmac As HMACSHA1 = New HMACSHA1(_sUsableKey)

            TpeHmac.Initialize()
            Dim bytes As Byte() = Encoding.ASCII.GetBytes(sData)
            Dim ba As Byte() = TpeHmac.ComputeHash(bytes)

            Return Me.byteArrayToHexString(ba)

        End Function

        Public Function isValidHmac(ByVal sChaineMAC As String, ByVal sMAC As String) As Boolean

            Return (Me.computeHmac(sChaineMAC) = sMAC.ToLower())

        End Function

        Private Function hexStringToByteArray(ByVal hs As String) As Object

            Dim xs As String = ""
            If hs.StartsWith("0x") Then
                xs &= hs.Substring(2, hs.Length - 2)
            Else
                xs &= hs
            End If

            Dim bal As Integer = xs.Length / 2
            If xs.Length <> 2 * bal Then
                xs = "0" & xs
            End If

            Dim ba((xs.Length / 2) - 1) As Byte
            Dim i As Integer

            For i = 0 To ba.Length - 1
                ba(i) = System.Convert.ToByte(xs.Substring(2 * i, 2), 16)
            Next i
            Return CType(ba.Clone(), Byte())

        End Function

        Private Function byteArrayToHexString(ByVal ba() As [Byte]) As Object

            Dim i As Integer
            Dim s As String = ""
            For i = 0 To ba.Length - 1
                s = s & ba(i).ToString("x2")
            Next i
            Return s

        End Function

    End Class

End Namespace
